package com.fone.player.view;



import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.util.Property;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;


import android.view.animation.Interpolator;


public class ColorBallProgressDrawable extends Drawable implements Animatable {
	
	static public class CustomLinearInterpolator implements Interpolator {
		 
	    @Override
	    public float getInterpolation(float t) {
	        if (t < 0.5f) {
	        	return t*2f/3f;
	        } else {
	        	return (float) (0.5f +2f*(t -0.5f))*2f/3f;
	        }
	        	
	    }
	}

	private static final Interpolator ANGLE_INTERPOLATOR = new CustomLinearInterpolator();//new DecelerateInterpolator();
	private static final int ANGLE_ANIMATOR_DURATION = 1200;
	private final RectF fBounds = new RectF();

	private ObjectAnimator mObjectAnimatorAngle;
	private Paint mPaint;
	private float mCurrentGlobalAngle;
	private float mBorderWidth;
	private boolean mRunning;
	private Bitmap mBitmap;
	private Matrix mMatrix;

	public ColorBallProgressDrawable(Bitmap bitmap, float borderWidth) {
		mBorderWidth = borderWidth;

		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeWidth(borderWidth);
		
		mBitmap = bitmap;
		mMatrix = new Matrix();
		
		setupAnimations();
	}

	@Override
	public void draw(Canvas canvas) {

		mMatrix.reset();

		float vw = canvas.getWidth();
		float vh = canvas.getHeight();
		float hvw = vw / 2;
		float hvh = vh / 2;
		float bw = (float) mBitmap.getWidth();
		float bh = (float) mBitmap.getHeight();

		// First scale the bitmap to fit into the view.
		// Use either scale factor for width and height,
		// whichever is the smallest.
		float s1x = vw / bw;
		float s1y = vh / bh;
		float s1 = (s1x < s1y) ? s1x : s1y;
		mMatrix.postScale(s1, s1);

		// Translate the image up and left half the height
		// and width so rotation (below) is around the center.
		mMatrix.postTranslate(-hvw, -hvh);

		mMatrix.postRotate(mCurrentGlobalAngle);
		
		mMatrix.postTranslate(hvw, hvh);

		canvas.drawBitmap(mBitmap, mMatrix, null);

	}

	@Override
	public void setAlpha(int alpha) {
		mPaint.setAlpha(alpha);
	}

	@Override
	public void setColorFilter(ColorFilter cf) {
		mPaint.setColorFilter(cf);
	}

	@Override
	public int getOpacity() {
		return PixelFormat.TRANSPARENT;
	}



	@Override
	protected void onBoundsChange(Rect bounds) {
		super.onBoundsChange(bounds);
		fBounds.left = bounds.left + mBorderWidth / 2f + .5f;
		fBounds.right = bounds.right - mBorderWidth / 2f - .5f;
		fBounds.top = bounds.top + mBorderWidth / 2f + .5f;
		fBounds.bottom = bounds.bottom - mBorderWidth / 2f - .5f;
	}

	// ////////////////////////////////////////////////////////////////////////////
	// ////////////// Animation

	private Property<ColorBallProgressDrawable, Float> mAngleProperty = new Property<ColorBallProgressDrawable, Float>(
			Float.class, "angle") {
		@Override
		public Float get(ColorBallProgressDrawable object) {
			return object.getCurrentGlobalAngle();
		}

		@Override
		public void set(ColorBallProgressDrawable object, Float value) {
			object.setCurrentGlobalAngle(value);
		}
	};


	private void setupAnimations() {
		mObjectAnimatorAngle = ObjectAnimator.ofFloat(this, mAngleProperty,
				720f);
		mObjectAnimatorAngle.setInterpolator(ANGLE_INTERPOLATOR);
		mObjectAnimatorAngle.setDuration(ANGLE_ANIMATOR_DURATION);
		mObjectAnimatorAngle.setRepeatMode(ValueAnimator.RESTART);
		mObjectAnimatorAngle.setRepeatCount(ValueAnimator.INFINITE);

	}

	@Override
	public void start() {
		if (isRunning()) {
			return;
		}
		mRunning = true;
		mObjectAnimatorAngle.start();
		invalidateSelf();
	}

	@Override
	public void stop() {
		if (!isRunning()) {
			return;
		}
		mRunning = false;
		mObjectAnimatorAngle.cancel();
		invalidateSelf();
	}

	@Override
	public boolean isRunning() {
		return mRunning;
	}

	public void setCurrentGlobalAngle(float currentGlobalAngle) {
		mCurrentGlobalAngle = currentGlobalAngle;
		invalidateSelf();
	}

	public float getCurrentGlobalAngle() {
		return mCurrentGlobalAngle;
	}
	
}